#include "dlgedittask.h"
#include "pmclientdata.h"
#include "main.h"
#include "pm/manager.h"
#include "pm/project.h"
#include "pm/tag.h"
#include <boost/foreach.hpp>

static
db::ID GetChoiceId(wxChoice* list, long item)
{
	return dynamic_cast<IdClientData*>(list->GetClientObject(item))->id();
}

static
void SelectChoiceId(wxChoice* list, db::ID id)
{
	for (size_t i = 0; i < list->GetCount(); ++i) {
		if (GetChoiceId(list, i) == id) {
			list->SetSelection(i);
			break;
		}
	}
}

double DlgEditTask::m_lastUnitCost = 0.0;

DlgEditTask::DlgEditTask(wxWindow* parent, const wxString& title, bool inWizardNewProject)
: DlgEditTaskGui(parent, wxID_ANY, title)
, m_bInWizardNewProject(inWizardNewProject)
{
	if (m_bInWizardNewProject) {
		m_listProject->Enable(false);
		m_listTag->Enable(false);
	}
	else {
		pm::ListProject listProject;
		pm::select_all(listProject);
		BOOST_FOREACH(const pm::Project& project, listProject) {
			m_listProject->Append(project.name(), new IdClientData(project.id()));
		}
		SelectChoiceId(m_listProject, wxGetApp().GetActiveProject());
		
		pm::ListTag listTag;
		pm::select_all(listTag);
		BOOST_FOREACH(const pm::Tag& tag, listTag) {
			m_listTag->Append(tag.name(), new IdClientData(tag.id()));
		}
		m_listTag->SetSelection(0);
	}
	
	// Set last unit cost
	m_sUnitCost.Printf(wxT("%.2f"), m_lastUnitCost);
	TransferDataToWindow();
}

void DlgEditTask::OnSubmit( wxCommandEvent& WXUNUSED(event) )
{
	if (TransferDataFromWindow() == false) {
		return;
	}
	
	double unitCost = 0;
	double quantity = 0;
	if (!m_sUnitCost.ToDouble(&unitCost) || !m_sQuantity.ToDouble(&quantity)) {
		return;
	}
	
	m_lastUnitCost = unitCost;
	
	db::ID idProject = db::Object::undefined;
	db::ID idTag     = db::Object::undefined;
	if (!m_bInWizardNewProject) {
		idProject = GetChoiceId(m_listProject, m_listProject->GetSelection());
		idTag     = GetChoiceId(m_listTag,     m_listTag->GetSelection());
	}
	
	m_task.name(m_editName->GetValue());
	m_task.unit_cost(unitCost);
	m_task.quantity(quantity);
	m_task.end_date(m_dpDate->GetValue());
	m_task.id_project(idProject);
	m_task.id_tag(idTag);
	
	EndModal(m_bInWizardNewProject || Submit() ? wxID_OK : wxID_CANCEL);
}

DlgNewTask::DlgNewTask(wxWindow* parent, bool inWizardNewProject)
: DlgEditTask(parent, _("New task"), inWizardNewProject)
{
}

bool DlgNewTask::Submit()
{
	if (pm::insert(m_task) == false) {
		wxLogError(_("Can't insert task !"));
		return false;
	}
	
	pmEvent<pm::Task> evt(pmEVT_TASK_ADDED, m_task);
	wxPostEvent(wxTheApp, evt);
	return true;
}

DlgUpdateTask::DlgUpdateTask(wxWindow* parent, const pm::Task& task, bool inWizardNewProject)
: DlgEditTask(parent, _("Update task"), inWizardNewProject)
{
	m_task = task;
	
	m_editName->SetValue(m_task.name());
	m_sUnitCost.Printf(wxT("%.2f"), m_task.unit_cost());
	m_sQuantity.Printf(wxT("%.2f"), m_task.quantity());
	m_dpDate->SetValue(m_task.end_date());
	SelectChoiceId(m_listProject, m_task.id_project());
	SelectChoiceId(m_listTag,     m_task.id_tag());
	// TODO : select project
	TransferDataToWindow();
}

bool DlgUpdateTask::Submit()
{
	if (pm::update(m_task) == false) {
		wxLogError(_("Can't update task !"));
		return false;
	}
	
	pmEvent<pm::Task> evt(pmEVT_TASK_UPDATED, m_task);
	wxPostEvent(wxTheApp, evt);
	return true;
}
